//
//  VerifyCodeTextField.swift
//  Lease_IOS
//
//  Created by Mr.wang on 2019/5/6.
//  Copyright © 2019 Mr.wang. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

class VerifyCodeTextField: UIView, UITextFieldDelegate {
    
    let textField = UITextField()
    let cursorView = UIView()
    var lineViews: [UIView] = []
    var labels: [UILabel] = []
    
    let lineWidth = 40
    let margin = 24
    var maxCount: Int = 0
    
    let codeFinishInput = PublishSubject<String>()
    
    init(count: Int) {
        super.init(frame: .zero)
        self.maxCount = count
        
        setupView()
    }
    
    func setupView() {
        textField.isSecureTextEntry = true
        textField.keyboardType = .numberPad
        textField.addTarget(self, action: #selector(textChanged(_:)), for: .editingChanged)
        textField.delegate = self
        textField.textColor = UIColor.clear
        self.addSubview(textField)
        textField.snp.makeConstraints { (make) in
            make.top.bottom.left.equalTo(0)
            make.width.equalTo(0)
        }
        
        let contentView = UIView()
        self.addSubview(contentView)
        contentView.snp.makeConstraints { (make) in
            make.center.equalTo(self.snp.center)
            make.width.equalTo(lineWidth * maxCount + margin * (maxCount - 1))
            make.height.equalTo(lineWidth)
        }
        
        for i in 0..<maxCount {
            let view = UIView()
            view.backgroundColor = .clear
            contentView.addSubview(view)
            view.snp.makeConstraints { (make) in
                make.left.equalTo((lineWidth + margin) * i)
                make.width.height.equalTo(lineWidth)
                make.centerY.equalTo(contentView.snp.centerY)
            }
            
            let line = UIView()
            line.backgroundColor = #colorLiteral(red: 0.9411764706, green: 0.9411764706, blue: 0.9411764706, alpha: 1)
            view.addSubview(line)
            line.snp.makeConstraints { (make) in
                make.left.bottom.right.equalTo(0)
                make.height.equalTo(2)
            }
            
            let label = UILabel()
            label.font = UIFont.boldSystemFont(ofSize: 25)
            view.addSubview(label)
            label.snp.makeConstraints { (make) in
                make.center.equalTo(view.snp.center)
            }
            
            lineViews.append(line)
            labels.append(label)
        }
        
        cursorView.backgroundColor = APPConfig.baseColor
        cursorView.frame = CGRect(x: 0, y: 0, width: 2, height: lineWidth - 10)
        cursorView.isHidden = true
        contentView.addSubview(cursorView)
        
        let animation = CABasicAnimation.init(keyPath: "opacity")
        animation.fromValue = NSNumber.init(value: 1)
        animation.toValue = NSNumber.init(value: 0)
        animation.autoreverses = true
        animation.duration = 0.5
        animation.repeatCount = MAXFLOAT
        animation.isRemovedOnCompletion = false
        animation.fillMode = .forwards
        animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeIn)
        cursorView.layer.add(animation, forKey: nil)
    }
    
    func clearAll() {
        textField.text = ""
        textChanged(textField)
    }
    
    func focusAt(_ index: Int) {
        cursorView.isHidden = true
        lineViews.forEach{ $0.backgroundColor = #colorLiteral(red: 0.9411764706, green: 0.9411764706, blue: 0.9411764706, alpha: 1) }
        if index >= lineViews.count { return }
        let line = lineViews[index]
        line.backgroundColor = APPConfig.baseColor
        cursorView.isHidden = false
        if let view = line.superview {
            cursorView.center = view.center
        }
    }
    
    @objc func textChanged(_ textField: UITextField) {
        let text = textField.text ?? ""
        focusAt(text.count)
        labels.forEach{ $0.text = "" }
        for (index, string) in text.enumerated() {
            labels[index].text = String(string)
        }
        if text.count == maxCount {
            codeFinishInput.onNext(text)
        }
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        let text = textField.text ?? ""
        focusAt(text.count)
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        focusAt(maxCount)
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let length = textField.text!.count + string.count - range.length
        if string.contains(" ") { return false }
        if string.count > 1 { return false }
        
        return length <= maxCount
    }
    
    @discardableResult
    override func becomeFirstResponder() -> Bool {
        return self.textField.becomeFirstResponder()
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textField.becomeFirstResponder()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

extension ObservableType where Element: Sequence {
    
    func forEach() -> Observable<Element.Element> {
        return Observable<Element.Element>.create { observer -> Disposable in
            let disposable = self.subscribe(onNext: { (sequence) in
                sequence.forEach{ observer.onNext($0) }
            }, onError: { (error) in
                observer.onError(error)
            }, onCompleted: {
                observer.onCompleted()
            })
            return Disposables.create([disposable])
        }
    }
    
}
